package org.linlinjava.litemall.admin.service;

import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.linlinjava.litemall.core.kdniao.dto.Order;
import org.linlinjava.litemall.core.kdniao.service.KdniaoService;
import org.linlinjava.litemall.core.util.ExportExcelUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.dao.LitemallRentOrderChangeMapper;
import org.linlinjava.litemall.db.dao.LitemallRentOrderMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.dto.ReturnBookDto;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.ExcelHeaderTemplateConstant;
import org.linlinjava.litemall.db.util.RentOrderConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.linlinjava.litemall.db.util.RentOrderConstant.*;
import static org.linlinjava.litemall.db.util.RentOrderConstant.STATUS_SHIP;

/**
 * @author Administrator
 */
@Service
public class AdminRentOrderService {
    @Autowired
    private LitemallGoodsProductService goodsProductService;
    @Autowired
    private LitemallOrderService orderService;
    @Autowired
    private LitemallRentOrderMapper rentOrderMapper;
    @Autowired
    private LitemallUserMemberService userMemberService;
    @Autowired
    private LitemallRentOrderService rentOrderService;
    @Autowired
    private KdniaoService kdniaoService;
    @Autowired
    private LitemallRentOrderDetailService rentOrderDetailService;
    @Autowired
    private LitemallWxExpressService wxExpressService;
    @Autowired
    private LitemallRentOrderChangeMapper rentOrderChangeMapper;

    /**
     * 将 买书/租书 订单中待发货的订单导出
     *
     * @param type
     * @param response
     * @return
     */
    public Object exportExcel(String type, HttpServletResponse response) {
        String[] header = null;
        List<List<String>> body = null;
        if (type.equals("买书")) {
            header = ExcelHeaderTemplateConstant.ORDER_HEADER_TEMPLATE;
            body = new ArrayList<>();

            List<LitemallOrder> litemallOrders = orderService.queryByShipWait();
            if (litemallOrders == null) {
                return ResponseUtil.fail(400, "没有待发货订单");
            }
            for (LitemallOrder litemallOrder : litemallOrders) {
                List<String> fieldList = new ArrayList<>();
                fieldList.add(litemallOrder.getConsignee());
                fieldList.add(litemallOrder.getOrderSn());
                fieldList.add(litemallOrder.getAddTime().toString());
                fieldList.add(litemallOrder.getAddress());
                fieldList.add(litemallOrder.getMobile());
                body.add(fieldList);
            }

        }
        if (type.equals("租书")) {
            header = ExcelHeaderTemplateConstant.RENT_ORDER_HEADER_TEMPLATE;
            body = new ArrayList<>();

            /* 租书待发货订单 */
            LitemallRentOrderExample example = new LitemallRentOrderExample();
            example.or().andRentOrderStatusEqualTo(STATUS_WAIT).andDeletedEqualTo(false);
            List<LitemallRentOrder> rentOrders = rentOrderMapper.selectByExample(example);

            /* 还书待发货订单 */
            LitemallRentOrderExample rentOrderBackExample = new LitemallRentOrderExample();
            example.or().andRentOrderStatusEqualTo(STATUS_RETURN_WAIT).andDeletedEqualTo(false);
            List<LitemallRentOrder> rentBackOrders = rentOrderMapper.selectByExample(rentOrderBackExample);

            if (rentBackOrders == null || rentOrders == null) {
                return ResponseUtil.fail(400, "没有待发货订单");
            }

            for (LitemallRentOrder rentOrder : rentOrders) {
                List<String> fieldList = new ArrayList<>();
                fieldList.add("租书");
                fieldList.add(rentOrder.getConsignee());
                fieldList.add(rentOrder.getRentOrderSn());
                fieldList.add(rentOrder.getAddress());
                fieldList.add(rentOrder.getMobile());
                fieldList.add(rentOrder.getShipBackSubscribeTime().toString());
                body.add(fieldList);
            }

            for (LitemallRentOrder rentBackOrder : rentBackOrders) {
                List<String> fieldList = new ArrayList<>();
                fieldList.add("租书");
                fieldList.add(rentBackOrder.getConsignee());
                fieldList.add(rentBackOrder.getRentOrderSn());
                fieldList.add(rentBackOrder.getAddress());
                fieldList.add(rentBackOrder.getMobile());
                fieldList.add(rentBackOrder.getShipBackSubscribeTime().toString());
                body.add(fieldList);
            }
        }
        HSSFWorkbook sheets = ExportExcelUtil.expExcel(header, body);
        String fileName = type + "待发货报表.xls";
        ExportExcelUtil.outFile(sheets, "D:\\" + fileName, response);
        return ResponseUtil.ok("已导出到您的D盘");
    }

    /**
     * 客户自己私下找物流或者自己上门送
     *
     * @param shipWay
     * @param shipperCode
     * @param logisticCode
     * @param rentOrderId
     * @return
     */
    public Object rentSelfDelivery(Integer shipWay, String shipperCode, String logisticCode, Integer rentOrderId) {
        LitemallRentOrder rentOrder = rentOrderService.findById(rentOrderId);
        if (rentOrder == null) {
            return ResponseUtil.fail(400, "该订单不存在");
        }
        if (!rentOrder.getRentOrderStatus().equals(STATUS_WAIT)) {
            return ResponseUtil.fail(400, "该订单不能发货");
        }
        switch (shipWay) {
            case 1:
                rentOrder.setShipWay(1);
                rentOrder.setRentOrderStatus(STATUS_SHIP);
                rentOrder.setShipTime(LocalDateTime.now());

                break;
            case 2:
                rentOrder.setShipWay(2);
                if (StringUtils.isEmpty(shipperCode) || StringUtils.isEmpty(logisticCode)) {
                    return ResponseUtil.fail(400, "物流公司编号和物流单号不能为空");
                }
                rentOrder.setShipChannel(shipperCode);
                String shipName = wxExpressService.queryByDeliveryId(shipperCode).getName();
                rentOrder.setShipChannelName(shipName);
                rentOrder.setShipSn(logisticCode);
                rentOrder.setRentOrderStatus(STATUS_SHIP);
                rentOrder.setShipTime(LocalDateTime.now());
                Integer userId = rentOrder.getUserId();
                LitemallUserMember userMember = userMemberService.findByUid(userId);
                if (userMember != null) {
                    userMember.setExpirationTime(userMember.getExpirationTime().plusDays(3));
                    userMemberService.updateById(userMember);
                }
                break;
            default:
                return ResponseUtil.fail(500, "shipWay 只能为1 或 2");
        }


        //  添加订单状态改变日期
        LitemallRentOrderChange orderChange = new LitemallRentOrderChange();
        orderChange.setRentOrderId(rentOrder.getId());
        orderChange.setRentOrderSn(rentOrder.getRentOrderSn());
        orderChange.setRentOrderTimeStatus(STATUS_SHIP);
        orderChange.setAddTime(LocalDateTime.now());
        orderChange.setUpdateTime(LocalDateTime.now());
        orderChange.setOrderStatusChangeTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        orderChange.setDeleted(false);
        rentOrderChangeMapper.insert(orderChange);
        rentOrderService.updateById(rentOrder);
        return rentOrder;
    }

    public Object confirmReturn(Integer rentOrderId) {
        LitemallRentOrder rentOrder = rentOrderService.findById(rentOrderId);

        rentOrder.setRentOrderStatus(STATUS_CONFIRM_RETURN);
        // 还书加库存
        List<LitemallRentOrderDetail> rentOrderDetails = rentOrderDetailService.queryByOid(rentOrderId);
        for (LitemallRentOrderDetail rentOrderDetail : rentOrderDetails) {
            goodsProductService.addStock(rentOrderDetail.getGoodsId(), rentOrderDetail.getNumber());
        }
        rentOrderService.updateById(rentOrder);
        return ResponseUtil.ok(rentOrder);
    }

    /**
     * 获取租书订单物流轨迹
     *
     * @param rentOrderId
     * @return
     */
    public Object getExpressTrace(Integer rentOrderId) {
        LitemallRentOrder rentOrder = rentOrderService.findById(rentOrderId);
        if (rentOrder == null) {
            return ResponseUtil.fail(400, "该订单不存在");
        }
        if (rentOrder.getShipWay().equals(1)) {
            return ResponseUtil.ok("同城配送，今日必达！");
        }
        try {
            return ResponseUtil.ok(kdniaoService.getOrderTracesByJson(new Order(rentOrder.getRentOrderSn(), rentOrder.getShipChannel(), rentOrder.getShipSn())));
        } catch (Exception e) {
            return ResponseUtil.fail(500, "获取物流轨迹失败");
        }
    }

    public List<Map<String, Object>> querySelective(String username, Integer status, Integer page, Integer limit, String sort, String order) {
        LitemallRentOrderExample example = new LitemallRentOrderExample();
        LitemallRentOrderExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        switch (status) {
            case 1:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_WAIT);
                break;
            case 2:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_SHIP);
                break;
            case 3:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CONFIRM);
                break;
            case 4:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_RETURN_WAIT);
                break;
            case 5:
                criteria.andRentOrderStatusEqualTo(RentOrderConstant.STATUS_CANCEL);
                break;
            case 0:
            default:
                break;
        }
        if (!StringUtils.isEmpty(username)) {
            criteria.andUserNameLike("%" + username + "%");
        }
        PageHelper.startPage(page, limit);
        if (!org.springframework.util.StringUtils.isEmpty(sort) && !org.springframework.util.StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        List<LitemallRentOrder> rentOrders = rentOrderMapper.selectByExample(example);
        if (rentOrders == null) {
            return null;
        }
        List<Map<String, Object>> data = new ArrayList<>();
        for (LitemallRentOrder rentOrder : rentOrders) {
            List<LitemallRentOrderDetail> rentOrderDetails = rentOrderDetailService.queryByOid(rentOrder.getId());
            Map<String, Object> orderMap = new HashMap<>();
            orderMap.put("rentOrder", rentOrder);
            orderMap.put("rentOrderStatusText", RentOrderConstant.rentOrderStatusText(rentOrder));
            orderMap.put("rentOrderDetails", rentOrderDetails);
            data.add(orderMap);
        }
        return data;
    }

    /**
     * 还书 自送或自己接物流
     *
     * @param shipWay
     * @param shipperCode
     * @param logisticCode
     * @param rentOrderId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Object rentBackSelfDelivery(Integer shipWay, String shipperCode, String logisticCode, Integer rentOrderId) {
        LitemallRentOrder rentOrder = rentOrderService.findById(rentOrderId);
        if (rentOrder == null) {
            return ResponseUtil.fail(400, "该订单不存在");
        }
        if (!rentOrder.getRentOrderStatus().equals(STATUS_RETURN_WAIT)) {
            return ResponseUtil.fail(400, "该订单不能发货");
        }
        switch (shipWay) {
            case 1:
                rentOrder.setShipBackWay(1);
                rentOrder.setRentOrderStatus(STATUS_RETURN_SHIP);
                rentOrder.setShipTime(LocalDateTime.now());
                break;
            case 2:
                rentOrder.setShipBackWay(2);
                if (StringUtils.isEmpty(shipperCode) || StringUtils.isEmpty(logisticCode)) {
                    return ResponseUtil.fail(400, "物流公司编号和物流单号不能为空");
                }
                rentOrder.setShipBackChannel(shipperCode);
                String shipName = wxExpressService.queryByDeliveryId(shipperCode).getName();
                rentOrder.setShipChannelName(shipName);
                rentOrder.setShipBackSn(logisticCode);
                rentOrder.setRentOrderStatus(STATUS_RETURN_SHIP);
                rentOrder.setShipTime(LocalDateTime.now());
                break;
            default:
                return ResponseUtil.fail(500, "shipWay 只能为1 或 2");
        }

        //  添加订单状态改变日期
        LitemallRentOrderChange orderChange = new LitemallRentOrderChange();
        orderChange.setRentOrderId(rentOrder.getId());
        orderChange.setRentOrderSn(rentOrder.getRentOrderSn());
        orderChange.setRentOrderTimeStatus(STATUS_RETURN_SHIP);
        orderChange.setAddTime(LocalDateTime.now());
        orderChange.setUpdateTime(LocalDateTime.now());
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        orderChange.setOrderStatusChangeTime(time);
        orderChange.setDeleted(false);
        rentOrderChangeMapper.insert(orderChange);


        rentOrderService.updateById(rentOrder);
        return rentOrder;
    }

    public Object rentBackConfirm(Integer id) {
        LitemallRentOrder rentOrder = rentOrderService.findById(id);
        if (rentOrder == null) {
            return ResponseUtil.fail(400, "该订单不存在");
        }
        if (!rentOrder.getRentOrderStatus().equals(STATUS_RETURN_SHIP)) {
            return ResponseUtil.fail(400, "该状态不能确认还书");
        }
        rentOrder.setRentOrderStatus(STATUS_CONFIRM_RETURN);
        // 还书加库存
        List<LitemallRentOrderDetail> rentOrderDetails = rentOrderDetailService.queryByOid(id);
        for (LitemallRentOrderDetail rentOrderDetail : rentOrderDetails) {
            goodsProductService.addStock(rentOrderDetail.getGoodsId(), rentOrderDetail.getNumber());
        }

        //  添加订单状态改变日期
        LitemallRentOrderChange orderChange = new LitemallRentOrderChange();
        orderChange.setRentOrderId(rentOrder.getId());
        orderChange.setRentOrderSn(rentOrder.getRentOrderSn());
        orderChange.setRentOrderTimeStatus(STATUS_CONFIRM_RETURN);
        orderChange.setAddTime(LocalDateTime.now());
        orderChange.setUpdateTime(LocalDateTime.now());
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        orderChange.setOrderStatusChangeTime(time);
        orderChange.setDeleted(false);
        rentOrderChangeMapper.insert(orderChange);

        rentOrderService.updateById(rentOrder);
        return ResponseUtil.ok();
    }

    public void updateSubscribeTime(ReturnBookDto returnBookDto) {
        Integer rentOrderId = returnBookDto.getRentOrderId();
        LocalDate shipBackSubscribeTime = returnBookDto.getShipBackSubscribeTime();
        String shipBackSubscribeDetailTime = returnBookDto.getShipBackSubscribeDetailTime();

        LitemallRentOrder rentOrder = rentOrderService.findById(rentOrderId);
        rentOrder.setShipBackSubscribeTime(shipBackSubscribeTime);
        rentOrder.setShipBackSubscribeDetailTime(shipBackSubscribeDetailTime);
        rentOrderService.updateById(rentOrder);
    }

    /**
     * 管理员终止还书流程
     *
     * @param rentOrderId
     * @return
     */
    @Transactional
    public Object adminReturnConfirm(Integer rentOrderId) {
        LitemallRentOrder rentOrder = rentOrderService.findById(rentOrderId);
        if (rentOrder == null) {
            return ResponseUtil.fail(400, "该订单不存在");
        }
        if (rentOrder.getRentOrderStatus() < 2 || rentOrder.getRentOrderStatus() > 3) {
            return ResponseUtil.fail(400, "管理员只能终结租书已发货和租书已收货订单");
        }

        rentOrder.setRentOrderStatus(STATUS_CONFIRM_RETURN);
        // 还书加库存
        List<LitemallRentOrderDetail> rentOrderDetails = rentOrderDetailService.queryByOid(rentOrderId);
        for (LitemallRentOrderDetail rentOrderDetail : rentOrderDetails) {
            goodsProductService.addStock(rentOrderDetail.getGoodsId(), rentOrderDetail.getNumber());
        }

        //  添加订单状态改变日期
        LitemallRentOrderChange orderChange = new LitemallRentOrderChange();
        orderChange.setRentOrderId(rentOrder.getId());
        orderChange.setRentOrderSn(rentOrder.getRentOrderSn());
        orderChange.setRentOrderTimeStatus(STATUS_CONFIRM_RETURN);
        orderChange.setAddTime(LocalDateTime.now());
        orderChange.setUpdateTime(LocalDateTime.now());
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        orderChange.setOrderStatusChangeTime(time);
        orderChange.setDeleted(false);
        rentOrderChangeMapper.insert(orderChange);

        rentOrderService.updateById(rentOrder);
        return ResponseUtil.ok();
    }
}
